package com.gper.edu.extractor

/**
 * 构造器 : 从给定的参数列表创建一个对象
 * 提取器 : 从传递它的对象中提取构造该对象的参数
 * 样例类是非常特殊，Scala会自动为其创建一个伴生对象：一个包含了 apply 和 unapply 方法的单列对象
 *    apply 方法用来创建样例类的实例。
 *    unapply 需要被伴生对象实现，以使其成为提取器。
 * 普通类要实现提取器的功能必须实现unapply方法。
 */
//抽象类
trait User{
  def firstName : String
  def lastName : String
  def score :Int
}

case class Person(name:String,age:Int)
/**
 *
 * @param firstName
 * @param lastName
 * @param score
 */
class FreeUser(val firstName : String,val lastName : String,val score :Int) extends User

/**
 *
 * @param firstName
 * @param lastName
 * @param score
 */
class PremiumUser(val firstName : String,val lastName : String,val score :Int) extends User

/**
 * FreeUser伴生对象
 */
object FreeUser{
  /**
   * 实现提取器功能
   * @param user
   * @return
   */
  def unapply(user: FreeUser): Option[(String, String, Int)] = Some(user.firstName,user.lastName,user.score)
}

/**
 * FreeUser伴生对象
 */
object PremiumUser{
  /**
   * 实现提取器功能
   * @param user
   * @return
   */
  def unapply(user: PremiumUser): Option[(String, String, Int)] = Some(user.firstName,user.lastName,user.score)
}

object UserExtractor{
  /**
   * 实现提取器功能
   * @param user
   * @return
   */
  def unapply(user:User) : Option[(String,String,Int)] = Some(user.firstName,user.lastName,user.score)

  def main(args: Array[String]): Unit = {
    val user = new FreeUser("guan","xianchun",90)
    /**
     * 在scala中没有switch语句，使用模式匹配来代替
     */
    var result = user match {
      case FreeUser(firstName,lastName,score) => s"Hello $firstName $lastName"
      case _ => "welcome .."
    }
    println(result)

    /**
     * 样例类的伴生对象已经有unapply方法，所以可以直接使用模式匹配
     */
    val person = new Person("ellis",28)
    val personResult = person match {
      //case 关键字、模式、可选的 守卫分句(guard clause)
      case Person(name,age) if age <=30 => s"Hello $name, your age is :$age ,you are yong."
      case Person(name,age) => s"Hello $name, your age is :$age ,you are not yong."
      case _ => "Hello world"
    }
    println(personResult)
    val wordFrequencies = ("habitual", 6) :: ("and", 56) :: ("consuetudinary", 2) ::
      ("additionally", 27) :: ("homely", 5) :: ("society", 13) :: Nil
    def wordsWithoutOutliers(wordFrequencies: Seq[(String, Int)]): Seq[String] =
      wordFrequencies.filter(wf => wf._2 > 3 && wf._2 < 25).map(_._1)
    println(wordsWithoutOutliers(wordFrequencies))
  }
}